<table class="exampleTable" > 
	<thead> 
		<tr> 
			<th colspan="3">页面访问</th>
		</tr> 
	</thead> 
	 <tbody> 
	 	<tr> 
			<td  width="30%">请求路径</td> 
			<td  width="70%" colspan="2">login.htm</td>
		</tr>
		<tr> 
			<td>请求方式</td> 
			<td colspan="2">GET</td>
		</tr>
		<tr> 
			<td>请求参数</td> 
			<td colspan="2"><a style="color: #317ee7" onclick="anchorJump('#anchor_500'); return false;">参数表</a></td>
		</tr>
		<tr>
			<td rowspan="1">返回值</td> 
			<td>表单验证码</td> 
			<td>
				变量：formCaptcha<br>
				类型：<a style="color: #317ee7" onclick="anchorJump('#anchor_10'); return false;">FormCaptcha</a>
			</td>
		</tr>
		<tr> 
			<td>说明</td> 
			<td colspan="2">
				1.当未登录用户访问需要登录的页面时URL会自动带有jumpUrl参数，为当前URL的Base64编码,可以设计登录成功后跳转到登录前页面功能<br>
				2.当未登录用户访问需要登录的页面时默认会自动跳转到登录页,Ajax提交的请求会返回jumpPath字段的请求头,值是要跳转的登录页
			</td>
		</tr>
	</tbody> 
</table>

<table class="exampleTable" > 
	<thead> 
		<tr> 
			<th colspan="3">页面访问 - AJAX方式</th>
		</tr> 
	</thead> 
	 <tbody> 
	 	<tr> 
			<td  width="30%">请求路径</td> 
			<td  width="70%" colspan="2">login.htm</td>
		</tr>
		<tr> 
			<td>请求方式</td> 
			<td colspan="2">GET</td>
		</tr>
		<tr> 
			<td>自定义请求头</td> 
			<td colspan="2">协议头：X-Requested-With  值：XMLHttpRequest</td>
		</tr>
		<tr> 
			<td width="30%" rowspan="4">请求成功返回</td> 
			<td width="30%" rowspan="4">JSON格式值 类型:<a style="color: #317ee7" onclick="anchorJump('#anchor_10'); return false;">FormCaptcha</a></td>
			<td width="40%">值内容说明：表单验证码</td> 
		</tr>
	</tbody> 
</table>


<table id="anchor_10" class="exampleTable" > 
	<thead> 
		<tr> 
			<th colspan="3">表单验证码 FormCaptcha</th>
		</tr> 
		<tr> 
			<th width="30%">变量</th> 
			<th width="30%">类型</th>
			<th width="40%">说明</th> 
		</tr> 
	</thead> 
	<tbody> 
		<tr> 
			<td>showCaptcha</td> 
			<td>boolean</td>
			<td>是否显示验证码</td>
		</tr>
		<tr> 
			<td>captchaKey</td> 
			<td>String</td>
			<td>验证码编号</td>
		</tr>
		<tr> 
			<td>说明</td> 
			<td colspan="2">Freemarker模板不支持直接输出布尔类型(boolean),布尔类型对象输出要使用内建函数c将布尔值转换为字符串；例如布尔类型${formCaptcha.showCaptcha}要写成${formCaptcha.showCaptcha?c}才能正确显示；比较${formCaptcha.showCaptcha?c == 'true'}</td>
		</tr>
	</tbody>
</table>

<table class="exampleTable" > 
	<thead> 
		<tr> 
			<th colspan="3">提交 会员登录 - 默认方式</th>
		</tr> 
	</thead> 
	 <tbody> 
	 	<tr> 
			<td width="30%" >请求路径</td> 
			<td width="70%" colspan="2">login.htm</td>
		</tr>
		<tr> 
			<td>请求方式</td> 
			<td colspan="2">POST</td>
		</tr>
		<tr> 
			<td>请求参数</td> 
			<td colspan="2"><a style="color: #317ee7" onclick="anchorJump('#anchor_600'); return false;">参数表</a></td>
		</tr>
		<tr> 
			<td>提交成功返回</td> 
			<td>默认跳转到jump模板页显示提交成功信息；跳转路径参数jumpUrl有值时按参数值路径跳转</td>
		</tr>
		<tr> 
			<td >提交失败返回</td> 
			<td>错误值</td> 
			<td width="30%" >
				变量：error<br>
				类型：<a style="color: #317ee7" onclick="anchorJump('#anchor_70'); return false;">Map&ltString,String></a><br>
			</td>
		</tr>
	</tbody> 
</table>
<table class="exampleTable" > 
	<thead> 
		<tr> 
			<th colspan="3">提交 会员登录 - AJAX方式</th>
		</tr> 
	</thead> 
	 <tbody> 
	 	<tr> 
			<td>请求路径</td> 
			<td colspan="2">login.htm</td>
		</tr>
		<tr> 
			<td>请求方式</td> 
			<td colspan="2">POST</td>
		</tr> 
		<tr> 
			<td>自定义请求头</td> 
			<td colspan="2">协议头：X-Requested-With  值：XMLHttpRequest</td>
		</tr>
		<tr> 
			<td>请求参数</td> 
			<td colspan="2"><a style="color: #317ee7" onclick="anchorJump('#anchor_600'); return false;">参数表</a></td>
		</tr>
		<tr> 
			<td width="30%" rowspan="7">提交返回</td> 
			<td width="30%" rowspan="7">JSON格式值 类型:Map&ltString,Object></td>
			<td width="40%">键参数：success<br>值内容说明：成功返回true 失败返回false<br>值类型：String</td> 
		</tr>
		<tr> 
			<td>键参数：error<br>值内容说明：错误值集合<br>值类型：<a style="color: #317ee7" onclick="anchorJump('#anchor_70'); return false;">Map&ltString,String></a></td> 
		</tr>
		<tr> 
			<td>键参数：captchaKey<br>值内容说明：验证码编号</td> 
		</tr>
		<tr> 
			<td>键参数：jumpUrl<br>值内容说明：登录前URL；success为true时有值</td> 
		</tr>
		<tr> 
			<td>键参数：systemUser<br>值内容说明：登录用户；success为true时有值<br>值类型：<a style="color: #317ee7" onclick="anchorJump('#anchor_30'); return false;">AccessUser</a></td> 
		</tr>
		<tr> 
			<td>键参数：accessToken<br>值内容说明：访问令牌</td> 
		</tr>
		<tr> 
			<td>键参数：refreshToken<br>值内容说明：刷新令牌</td> 
		</tr>
	</tbody> 
</table>

<table id="anchor_30" class="exampleTable" > 
	<thead> 
		<tr> 
			<th colspan="3">用户 AccessUser</th>
		</tr> 
		<tr> 
			<th width="30%">变量</th> 
			<th width="30%">类型</th>
			<th width="40%">说明</th> 
		</tr> 
	</thead> 
	<tbody> 
		<tr> 
			<td>id</td> 
			<td>long</td>
			<td>Id</td>
		</tr>
		<tr> 
			<td>account</td> 
			<td>String</td>
			<td>账号</td>
		</tr>
	</tbody> 
</table>

<table class="exampleTable" > 
	<thead> 
		<tr> 
			<th colspan="3">校验验证码</th>
		</tr> 
	</thead> 
	 <tbody> 
	 	<tr> 
			<td>请求路径</td> 
			<td colspan="2">checkCaptcha.htm</td>
		</tr>
		<tr> 
			<td>请求方式</td> 
			<td colspan="2">GET</td>
		</tr> 
		<tr> 
			<td>返回类型</td> 
			<td colspan="2">JSON</td>
		</tr> 
		<tr> 
			<td>必填参数</td> 
			<td colspan="2">
				captchaKey : 验证码编号<br>
				captchaValue : 验证码值  同一编号验证码每分钟提交次数不能超过60次,超出时验证码图片返回空字符
			</td>
		</tr>
		<tr> 
			<td width="30%" >提交返回</td> 
			<td width="30%" >字符串格式值 类型:String</td>
			<td width="40%">值内容说明：成功返回true 失败返回false<br>值类型：String</td> 
		</tr>
	</tbody> 
</table>
<table id="anchor_70"  class="exampleTable" > 
	<thead> 
		<tr> 
			<th colspan="3">会员登录 错误值 error</th>
		</tr> 
		<tr> 
			<th width="30%">变量</th> 
			<th width="30%">类型</th>
			<th width="40%">说明</th> 
		</tr> 
	</thead> 
	 <tbody> 
	 	<tr> 
			<td>account</td> 
			<td>String</td>
			<td>账号错误</td>
		</tr>
		<tr> 
			<td>mobile</td> 
			<td>String</td>
			<td>手机号错误</td>
		</tr>
		<tr> 
			<td>type</td> 
			<td>Integer</td>
			<td>用户类型错误</td>
		</tr>
		<tr> 
			<td>password</td> 
			<td>String</td>
			<td>密码错误</td>
		</tr>
		<tr> 
			<td>captchaValue</td> 
			<td>String</td>
			<td>验证码错误</td>
		</tr>
	 	<tr> 
			<td>token</td> 
			<td>String</td>
			<td>令牌错误</td>
		</tr>
	</tbody> 
</table>
<table id="anchor_500" class="exampleTable" > 
	<thead>
		<tr> 
			<th colspan="4">访问'会员登录'页参数</th>
		</tr>
		<tr> 
			<th width="30%">参数</th> 
			<th width="20%">类型</th> 
			<th width="10%">是否必填</th> 
			<th width="40%">说明</th> 
		</tr> 
	</thead> 
	 <tbody>
	 	<tr> 
			<td>code</td> 
			<td>String</td>
			<td>按需填写</td>
			<td>微信公众号code 在微信浏览器使用此参数可以实现保持登录状态</td> 
		</tr>
	</tbody> 
</table>
<table id="anchor_600" class="exampleTable" > 
	<thead>
		<tr> 
			<th colspan="4">提交'会员登录'参数</th>
		</tr>
		<tr> 
			<th width="30%">参数</th> 
			<th width="20%">类型</th> 
			<th width="10%">是否必填</th> 
			<th width="40%">说明</th> 
		</tr> 
	</thead> 
	 <tbody>
	 	<tr> 
			<td>account</td> 
			<td>String</td>
			<td>按需填写</td>
			<td>账号</td> 
		</tr>
		<tr> 
			<td>type</td> 
			<td>Integer</td>
			<td>是</td>
			<td>用户类型</td> 
		</tr>
		<tr> 
			<td>mobile</td> 
			<td>String</td>
			<td>按需填写</td>
			<td>手机号</td> 
		</tr>
	 	<tr> 
			<td>password</td> 
			<td>String</td>
			<td>是</td>
			<td>密码 必须执行sha256一次</td> 
		</tr>
		<tr> 
			<td>captchaKey</td> 
			<td>String</td>
			<td>按需填写</td>
			<td>验证码编号</td> 
		</tr>
		<tr>
			<td>captchaValue</td> 
			<td>String</td>
			<td>按需填写</td>
			<td>验证码值 同一编号验证码每分钟提交次数不能超过60次,超出时验证码图片返回空字符</td> 
		</tr>
		<tr> 
			<td>token</td> 
			<td>String</td>
			<td>是</td>
			<td>令牌</td> 
		</tr>
		<tr> 
			<td>thirdPartyOpenId</td> 
			<td>String</td>
			<td>按需填写</td>
			<td>第三方用户获取唯一标识  例如微信公众号openid</td> 
		</tr>
		<tr> 
			<td>jumpUrl</td> 
			<td>String</td>
			<td>否</td>
			<td>'提交表单 - 默认方式'提交成功后跳转路径,不填写默认跳转到首页；参数必须经过encodeBase64URL编码后才能提交。例${encodeBase64URL('/index')}</td> 
		</tr>
	</tbody> 
</table>

<h2 style="margin:0;padding:0; margin-top: 10px;">示例</h2>
<textarea name="exampleCode">


<form id="loginForm" name="login" method="post" autocomplete="off" action="login?jumpUrl=${url_jumpUrl}">
	<!-- 令牌标记 -->
	<input type="hidden" id="token" name="token" value="${token}">
      
      
	<#-- 账号 -->   
    <input id="account" name="account" type="text" maxLength="40" value="" />
      
    <#-- 用户名错误 --> 
    ${(error['account'])!}
    
    <#-- 密码 -->  
    <input id="password" name="password" type="password" maxLength="20" value="" />
    
    <#-- 密码错误 -->  
    ${(error['password'])!}
    
    
    <#-- 验证码 -->
	<input type="hidden" id="captchaKey" name="captchaKey" value="${formCaptcha.captchaKey}">
	<#-- 验证码值 -->
	<input id="captchaValue" name="captchaValue" type="text" value=""/>		
	<#-- 验证码图片 -->
	&ltimg id="captcha" src="captcha/${formCaptcha.captchaKey!}.jpg"/>
	<#-- 验证码错误 -->
	${(error['captchaValue'])!}
    
    <#-- 令牌错误 -->
	${error['token']}
 
	<#-- 密码必须使用sha256加密一次才能提交 CryptoJS.SHA256(password) -->
	<input type="submit" value="默认提交" />
	
	<#-- ajax提交请看下面示例 -->
	<input type="button" value="ajax提交" onClick="javascript:ajaxSubmit();">
	
</form>


<#-- 组装提交参数 必须引入cryptoJS/core.js 和cryptoJS/sha256.js -->
<script type="text/javascript" language="javascript"> 
		
//组装参数
function getParameter(){
	var parameter = "";

	//url跳转参数
	var jumpUrl = getUrlParam("jumpUrl");
	if(jumpUrl != null){
		parameter += "&jumpUrl="+encodeURIComponent(jumpUrl);
	}
	//令牌标记
	var token = document.getElementById("token").value;
	parameter += "&token="+token;
	
	//验证码Key
	var captchaKey = document.getElementById("captchaKey");
	if(captchaKey != null){
		parameter += "&captchaKey="+encodeURIComponent(captchaKey.value);
	}
	//验证码值
	var captchaValue = document.getElementById("captchaValue");
	if(captchaValue != null){
		parameter += "&captchaValue="+encodeURIComponent(captchaValue.value);
	}

	//账号
	var account = document.getElementById("account").value;
	parameter += "&account="+encodeURIComponent(account);
	//密码需SHA256加密
	var password = document.getElementById("password").value;
	if(password != ""){
		//password在加密前要原始数据，不能进行任何转义
		parameter += "&password="+ CryptoJS.SHA256(password);
	}
	


	//删除第一个&号,防止因为多了&号而出现警告: Parameters: Invalid chunk ignored.信息
	if(parameter.indexOf("&") == 0){
		parameter = parameter.substring(1,parameter.length);
	}
	return parameter;
}




</script>

<#-- ajax提交示例 -->
<script type="text/javascript" language="javascript"> 
	//ajax提交
	function ajaxSubmit(){
		//直接将组装好的参数提交即可
		var parameter = getParameter();
	
	}
</script>


</textarea>


<table class="exampleTable" > 
	<thead> 
		<tr> 
			<th colspan="3">提交 会员退出 - 默认方式</th>
		</tr> 
	</thead> 
	 <tbody> 
	 	<tr> 
			<td width="30%" >请求路径</td> 
			<td width="70%" colspan="2">logout.htm</td>
		</tr>
		<tr> 
			<td>请求方式</td> 
			<td colspan="2">POST</td>
		</tr>
		<tr> 
			<td>请求参数</td> 
			<td>令牌</td> 
			<td>
				变量：token<br>
				类型：String
			</td>
		</tr>
		<tr> 
			<td>提交成功返回</td> 
			<td colspan="2">跳转到login.htm页</td>
		</tr>
		<tr> 
			<td >提交失败返回</td> 
			<td colspan="2">跳转到index.htm页</td> 
		</tr>
	</tbody> 
</table>
<h2 style="margin:0;padding:0; margin-top: 10px;">示例</h2>
<textarea name="exampleCode">
<a href="" onClick="javascript:document.getElementById('logout').submit();return false;">退出</a>
<form id="logout" action="logout.htm?token=${token}" method="post" ></form>
</textarea>